{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Stellargraph example: Relational Graph Convolutional Network (RGCN) on the AIFB relational dataset\n",
    "\n",
    "This example demonstrates how use an RGCN [1] on the AIFB dataset with stellargraph. \n",
    "\n",
    "[1] Modeling Relational Data with Graph Convolutional Networks. Thomas N. Kipf, Michael Schlichtkrull (2017). https://arxiv.org/pdf/1703.06103.pdf"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First we load the required libraries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "from rdflib.extras.external_graph_libs import *\n",
    "from rdflib import Graph, URIRef, Literal\n",
    "\n",
    "import networkx as nx\n",
    "from networkx.classes.function import info\n",
    "\n",
    "import stellargraph as sg\n",
    "from stellargraph.mapper import RelationalFullBatchNodeGenerator\n",
    "from stellargraph.layer import RGCN\n",
    "\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import os\n",
    "import pandas as pd\n",
    "\n",
    "import tensorflow as tf\n",
    "from tensorflow import keras\n",
    "from tensorflow.keras.layers import Dense\n",
    "from tensorflow.keras.models import Model\n",
    "\n",
    "import sklearn\n",
    "from sklearn import model_selection\n",
    "from collections import Counter\n",
    "from stellargraph import datasets\n",
    "from IPython.display import display, HTML"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Loading the data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "The AIFB dataset describes the AIFB research institute in terms of its staff, research group, and publications. First used for machine learning with RDF in Bloehdorn, Stephan and Sure, York, \"Kernel Methods for Mining Instance Data in Ontologies\", The Semantic Web (2008), http://dx.doi.org/10.1007/978-3-540-76298-0_5. It contains ~8k entities, ~29k edges, and 45 different relationships or edge types. In (Bloehdorn et al 2007) the dataset was first used to predict the affiliation (i.e., research group) for people in the dataset. The dataset contains 178 members of a research group with 5 different research groups. The goal is to predict which research group a researcher belongs to."
      ],
      "text/plain": [
       "<IPython.core.display.HTML object>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "dataset = datasets.AIFB()\n",
    "display(HTML(dataset.description))\n",
    "dataset.download()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We use `rdflib` to load the relational dataset into a networkx directed multigraph. Relational datasets are inherently directed with multiple edges types so we use the `MultiDiGraph` data structure to capture this information.\n",
    "\n",
    "The relationship 'affiliation' indicates whether a researcher is affiliated with a reseach group e.g. (researcher, research group, affilliation). We use this relationship to label the nodes in the AIFB dataset.  After this we remove the affiliation relationship to prevent giving away the answer. The idea here is to test whether we can recover a 'missing' relationship. \n",
    "\n",
    "The relation 'employs' is the inverse of 'affilliation' and we remove this as well - otherwise it would give away the answer."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "data_filepath = os.path.join(dataset.data_directory, \"aifbfixed_complete.n3\")\n",
    "\n",
    "graph = Graph()\n",
    "graph.parse(data_filepath, format=\"n3\")\n",
    "g_nx = rdflib_to_networkx_multidigraph(\n",
    "    graph, edge_attrs=lambda s, p, o: {\"label\": str(p)}\n",
    ")\n",
    "\n",
    "affiliation = \"http://swrc.ontoware.org/ontology#affiliation\"\n",
    "employs = \"http://swrc.ontoware.org/ontology#employs\"\n",
    "\n",
    "\n",
    "people_nodes = [\n",
    "    src for src, _, data in g_nx.edges(data=True) if data[\"label\"] == affiliation\n",
    "]  # the node ids of the researchers\n",
    "labels = [\n",
    "    dst for _, dst, data in g_nx.edges(data=True) if data[\"label\"] == affiliation\n",
    "]  # the research group each researcher belongs to\n",
    "\n",
    "# remove 'affiliation' and 'employs' relationships\n",
    "edges_to_remove = [\n",
    "    e\n",
    "    for e in g_nx.edges(keys=True, data=True)\n",
    "    if e[-1][\"label\"] == affiliation or e[-1][\"label\"] == employs\n",
    "]\n",
    "g_nx.remove_edges_from(edges_to_remove)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Feature and target creation\n",
    "\n",
    "We now create features and targets for machine learning.  Our nodes don't have features so we simply one-hot-encode each node and use there as our features and allow our model to learn from the graph structure."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# create an encoder\n",
    "encoder = sklearn.preprocessing.OneHotEncoder(sparse=False)\n",
    "\n",
    "# create targets\n",
    "# the targets are one hot encoded vectors indicating which research group a researcher belongs to\n",
    "# targets of non-researcher entities are set to zero vectors\n",
    "# (we're not interested in predicting anything about non-researcher nodes)\n",
    "\n",
    "node_index = dict(zip(g_nx.nodes, range(len(g_nx.nodes))))\n",
    "people_idx = np.array([node_index[node] for node in people_nodes])\n",
    "\n",
    "people_targets = encoder.fit_transform(np.array(labels)[:, np.newaxis])\n",
    "\n",
    "targets = np.zeros((len(g_nx.nodes), people_targets.shape[-1]))\n",
    "targets[people_idx, :] = people_targets\n",
    "\n",
    "# index the node_data and targets dataframes by the nodes of the graph - this allows\n",
    "# the nodes and edges of the graph to be matched with the targets and features\n",
    "node_data = pd.DataFrame(np.eye(len(g_nx.nodes)), index=g_nx.nodes)\n",
    "targets = pd.DataFrame(targets, index=g_nx.nodes)\n",
    "\n",
    "# split data into train and test\n",
    "train_data, test_data, train_targets, test_targets = model_selection.train_test_split(\n",
    "    node_data.loc[people_nodes], targets.loc[people_nodes], train_size=0.8, test_size=None\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Machine Learning Graph Creation\n",
    "\n",
    "Now we create a StellarDiGraph object to encapsulate the graph structure and the node features.  We'll then use the StellarDiGraph to create training and testing generators for ML."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "G = sg.StellarDiGraph(g_nx, node_features=node_data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "generator = RelationalFullBatchNodeGenerator(G, sparse=True)\n",
    "\n",
    "train_gen = generator.flow(train_data.index, targets=train_targets)\n",
    "test_gen = generator.flow(test_data.index, targets=test_targets)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## RGCN model creation and training\n",
    "\n",
    "We use stellargraph to create an RGCN object. This creates a stack of relational graph convolutional layers. We add a softmax layer to transform the features created by RGCN into class predictions and create a keras model.  Then we train the model on the stellargraph generators.\n",
    "\n",
    "Each RGCN layer creates a weight matrix for each relationship in the graph. If `num_bases==0` these weight matrices are completely independent. If `num_bases!=0` each weight matrix is a different linear combination of the same basis matrices. This introduces parameter sharing and reduces the number of the parameters in the model.  See the paper for more details."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "rgcn = RGCN(\n",
    "    layer_sizes=[32, 32],\n",
    "    activations=[\"relu\", \"relu\"],\n",
    "    generator=generator,\n",
    "    bias=True,\n",
    "    num_bases=20,\n",
    "    dropout=0.5,\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "x_in, x_out = rgcn.build()\n",
    "predictions = Dense(train_targets.shape[-1], activation=\"softmax\")(x_out)\n",
    "model = Model(inputs=x_in, outputs=predictions)\n",
    "model.compile(\n",
    "    loss=\"categorical_crossentropy\",\n",
    "    optimizer=keras.optimizers.Adam(0.01),\n",
    "    metrics=[\"acc\"],\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "history = model.fit_generator(train_gen, validation_data=test_gen, epochs=20)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "\n",
    "def remove_prefix(text, prefix):\n",
    "    return text[text.startswith(prefix) and len(prefix):]\n",
    "\n",
    "def plot_history(history):\n",
    "    metrics = sorted(set([remove_prefix(m, \"val_\") for m in list(history.history.keys())]))\n",
    "    for m in metrics:\n",
    "        # summarize history for metric m\n",
    "        plt.plot(history.history[m])\n",
    "        plt.plot(history.history['val_' + m])\n",
    "        plt.title(m)\n",
    "        plt.ylabel(m)\n",
    "        plt.xlabel('epoch')\n",
    "        plt.legend(['train', 'test'], loc='best')\n",
    "        plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    },
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "plot_history(history)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we assess the accuracy of our trained model on the test set - it does pretty well on this example dataset!"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Test Set Metrics:\n",
      "\tloss: 0.2345\n",
      "\tacc: 0.9444\n"
     ]
    }
   ],
   "source": [
    "test_metrics = model.evaluate_generator(test_gen)\n",
    "print(\"\\nTest Set Metrics:\")\n",
    "for name, val in zip(model.metrics_names, test_metrics):\n",
    "    print(\"\\t{}: {:0.4f}\".format(name, val))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Node embeddings\n",
    "\n",
    "We evaluate node embeddings as the activations of the output of the last graph convolution layer in the GCN layer stack and visualise them, coloring nodes by their true subject label. We expect to see nice clusters of researchers in the node embedding space, with researchers from the same group belonging to the same cluster.\n",
    "\n",
    "To calculate the node embeddings rather than the class predictions, we create a new model with the same inputs as we used previously `x_inp` but now the output is the embeddings `x_out` rather than the predicted class. Additionally note that the weights trained previously are kept in the new model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "from sklearn.decomposition import PCA\n",
    "from sklearn.manifold import TSNE\n",
    "\n",
    "# get embeddings for all people nodes\n",
    "all_gen = generator.flow(people_nodes, targets=people_targets)\n",
    "embedding_model = Model(inputs=x_in, outputs=x_out)\n",
    "emb = embedding_model.predict_generator(all_gen)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [],
   "source": [
    "X = emb.squeeze(0)\n",
    "y = np.argmax(people_targets, axis=1)\n",
    "\n",
    "if X.shape[1] > 2:\n",
    "    transform = TSNE\n",
    "\n",
    "    trans = transform(n_components=2)\n",
    "    emb_transformed = pd.DataFrame(trans.fit_transform(X), index=people_nodes)\n",
    "    emb_transformed[\"label\"] = y\n",
    "else:\n",
    "    emb_transformed = pd.DataFrame(X, index=people_nodes)\n",
    "    emb_transformed = emb_transformed.rename(columns={\"0\": 0, \"1\": 1})\n",
    "    emb_transformed[\"label\"] = y"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 504x504 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "alpha = 0.7\n",
    "\n",
    "fig, ax = plt.subplots(figsize=(7, 7))\n",
    "ax.scatter(\n",
    "    emb_transformed[0],\n",
    "    emb_transformed[1],\n",
    "    c=emb_transformed[\"label\"].astype(\"category\"),\n",
    "    cmap=\"jet\",\n",
    "    alpha=alpha,\n",
    ")\n",
    "ax.set(aspect=\"equal\", xlabel=\"$X_1$\", ylabel=\"$X_2$\")\n",
    "plt.title(\n",
    "    \"{} visualization of RGCN embeddings for AIFB dataset\".format(transform.__name__)\n",
    ")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Aside from a slight overlap the classes are well seperated despite only using 2-dimensions. This indicates that our model is performing well at clustering the researchers into the right groups."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.9"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
